package com.wangp.五张表.service.impl;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wangp.五张表.DO.RolePermissionDO;
import com.wangp.五张表.DO.PermissionDO;
import com.wangp.五张表.DO.RoleDO;

import com.wangp.五张表.DO.UserDO;
import com.wangp.五张表.DO.UserRoleDO;

import com.wangp.五张表.dto.PermissionDTO;
import com.wangp.五张表.dto.UserRolePermissionDTO;
import com.wangp.五张表.dto.request.UserQueryListRequest;
import com.wangp.五张表.dto.response.UserQueryListResponse;
import com.wangp.五张表.mapper.*;
import com.wangp.五张表.service.UserService;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;


    @Override
    public void test() {

        LambdaQueryWrapper<UserDO> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(UserDO::getIsDeleted,0);
        List<UserDO> userDOS = userMapper.selectList(userWrapper);

        LambdaQueryWrapper<RoleDO> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(RoleDO::getIsDeleted,0);
        List<RoleDO> roleDOS = roleMapper.selectList(roleWrapper);

        LambdaQueryWrapper<PermissionDO> perWrapper = new LambdaQueryWrapper<>();
        perWrapper.eq(PermissionDO::getIsDeleted,0);
        List<PermissionDO> permissionDOS = permissionMapper.selectList(perWrapper);

        log.info(JSONObject.toJSONString(userDOS, true));
        log.info(JSONObject.toJSONString(roleDOS, true));
        log.info(JSONObject.toJSONString(permissionDOS, true));
    }


    @Override
    public List<UserQueryListResponse> queryPage(UserQueryListRequest userQueryListRequest) {
        this.check(userQueryListRequest);

        List<UserQueryListResponse> userRespList = new ArrayList<>();

        // 1. query
        //1.1拿到前端传的username
        String username = userQueryListRequest.getUsername();
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getIsDeleted, 0)
            .orderByDesc(UserDO::getCreateTime);
        if (StringUtils.isNotBlank( userQueryListRequest.getUsername())){
            //1.2 如果username不包含“，”号
            if(!username.contains(",")){
                queryWrapper.like(UserDO::getUsername,userQueryListRequest.getUsername());
            }else {
                //如果username包含“，”号
                String[] names = username.split(",");
                for (int i = 0; i < names.length; i++) {
                    names[i] = names[i].trim();
                }
                for (String keyword : names) {
                    queryWrapper.or();
                    queryWrapper.like(UserDO::getUsername, keyword);
                }
            }
        }
        IPage<UserDO> resultPage = userMapper.selectPage(new Page<>(userQueryListRequest.getPage(), userQueryListRequest.getSize()), queryWrapper);
        List<UserDO> records = resultPage.getRecords();
        long count = userMapper.selectCount(queryWrapper);


        // 2. build   user
        List<UserRolePermissionDTO> userDataRespList = this.convert(records);


        for ( UserRolePermissionDTO userRolePermissionDTO : userDataRespList) {
            // 角色 权限表
            List<Integer> collectRoleIdList = this.getCurrentUserRoleIdList(userRolePermissionDTO);
            List<String> roleNameList = this.getCurrentUserRoleNameListByRoleIdList(userQueryListRequest,collectRoleIdList);


            //权限表
            List<Integer> permissionIds = this.getCurrentPermissionIdsByRoleIdList(collectRoleIdList);
            List<PermissionDTO> permissionNameList = this.buildCurrentPermissionNameListById(permissionIds, userQueryListRequest);

            userRolePermissionDTO.setRoleNameList(roleNameList);
            userRolePermissionDTO.setPermissionNameList(permissionNameList);

        }

        UserQueryListResponse userQueryResp = new UserQueryListResponse();
        userQueryResp.setPage(userQueryListRequest.getPage());
        userQueryResp.setSize(userQueryListRequest.getSize());
        userQueryResp.setTotal(count);
        userQueryResp.setData(userDataRespList);
        userRespList.add(userQueryResp);
        return userRespList;
    }

    private void check(UserQueryListRequest userQueryListRequest) {
            // 1. 检查请求参数有效性
            if (userQueryListRequest == null) {
                throw new IllegalArgumentException("请求参数不能为空");
            }
            if (userQueryListRequest.getPage() <= 0 || userQueryListRequest.getSize() <= 0) {
                throw new IllegalArgumentException("分页参数page和size必须大于0");
            }
    }

    private List<PermissionDTO> buildCurrentPermissionNameListById(final List<Integer> permissionIds,
                                                    UserQueryListRequest userQueryListRequest) {
        //
        if (CollectionUtils.isEmpty(permissionIds)){
            return new ArrayList<>();
        }
        List<PermissionDTO> permissionNameList = new ArrayList<>();
        LambdaQueryWrapper<PermissionDO> permissionWrapper = new LambdaQueryWrapper<>();
        permissionWrapper.eq(PermissionDO::getIsDeleted,0 );

        permissionWrapper.in(PermissionDO::getId, permissionIds);

        if (StringUtils.isNotBlank(userQueryListRequest.getRoleName())){
            permissionWrapper.like(PermissionDO::getPermissionName,userQueryListRequest.getPermissionName());
        }
        List<PermissionDO> permissionDOList = permissionMapper.selectList(permissionWrapper);
        // List<PermissionDO> permissionDOList = permissionMapper.selectBatchIds(permissionIds);
        for (final PermissionDO permissionDO : permissionDOList) {
            PermissionDTO permissionDTO=new PermissionDTO();
            BeanUtils.copyProperties(permissionDO,permissionDTO);
            permissionNameList.add(permissionDTO);
        }
        return  permissionNameList;
    }

    private List<Integer> getCurrentPermissionIdsByRoleIdList(final List<Integer> collectRoleIdList) {
        if (CollectionUtils.isEmpty(collectRoleIdList)){
            return new ArrayList<>();
        }
        List<Integer> permissionIds = new ArrayList<>();
        for (final Integer roleId : collectRoleIdList) {
            LambdaQueryWrapper<RolePermissionDO> rolePermissionWrapper = new LambdaQueryWrapper<>();
            rolePermissionWrapper.eq(RolePermissionDO::getRoleId, roleId);
            List<RolePermissionDO> rolePermissionDOList = rolePermissionMapper.selectList(rolePermissionWrapper);
            Set<Integer> uniquePermissionSet= rolePermissionDOList.stream()
                .map(RolePermissionDO::getPermissionId)
                .collect(Collectors.toSet());
            permissionIds.addAll(uniquePermissionSet);
        }
        return permissionIds;
    }

    private List<String> getCurrentUserRoleNameListByRoleIdList( UserQueryListRequest userQueryListRequest,final List<Integer> collectRoleId) {
        if (CollectionUtils.isEmpty(collectRoleId)){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<RoleDO> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(RoleDO::getIsDeleted,0);


        roleWrapper.in(RoleDO::getId, collectRoleId);

        if (StringUtils.isNotBlank(userQueryListRequest.getRoleName())){
            roleWrapper.like(RoleDO::getRoleName,userQueryListRequest.getRoleName());
        }
        List<RoleDO> roleDOList = roleMapper.selectList(roleWrapper);
        return roleDOList.stream().map(RoleDO::getRoleName).collect(Collectors.toList());


    }

    private List<Integer> getCurrentUserRoleIdList(final UserRolePermissionDTO userRolePermissionDTO) {
        LambdaQueryWrapper<UserRoleDO> userRoleWrapper = new LambdaQueryWrapper<>();
        userRoleWrapper.eq(UserRoleDO::getUserId, userRolePermissionDTO.getId());
        List<UserRoleDO> userRoleDOList = userRoleMapper.selectList(userRoleWrapper);
        return userRoleDOList.stream()
            .map(UserRoleDO::getRoleId)
            .collect(Collectors.toList());
    }

    private List<UserRolePermissionDTO> convert( List<UserDO> records){
        List<UserRolePermissionDTO> userDataRespList = new ArrayList<>();
        for (final UserDO record : records) {
            UserRolePermissionDTO userDTO = new UserRolePermissionDTO();
            userDTO.setId(record.getId());
            userDTO.setUsername(record.getUsername());
            userDTO.setEmail(record.getEmail());

            Date createTime = record.getCreateTime();
            Date updateTime = record.getUpdateTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formatCreateTime = sdf.format(createTime);
            String formatUpdateTime = sdf.format(updateTime);
            userDTO.setCreateTime(formatCreateTime);
            userDTO.setUpdateTime(formatUpdateTime);

            userDTO.setCreateBy(record.getCreateBy());
            userDTO.setUpdateBy(record.getUpdateBy());

            userDataRespList.add(userDTO);
        }
        return userDataRespList;
    }



}



